#include "Engine.h"
#include "Defines.h"
#include <stack>

Engine::Engine(void)
{
	window.Create(sf::VideoMode(800,600,32),"Test");
}

Engine::Engine( const std::string& settingsFilename )
{
	window.Create(sf::VideoMode(800,600,32),"Test");
	m_settings.Load(settingsFilename);
}
Engine::~Engine(void)
{
}

bool Engine::Execute( Module* m_module )
{
	if(!m_module) return false;

	m_module->SetWindow(&window);
	m_module->OnOpen();

	sf::Clock time;
	sf::Event event;
	time.Reset();
	float diff = 0;

	while (m_module->IsRunning()) {

		while (window.GetEvent(event)) {
			m_module->DispatchEvent(event);
		}
		if (m_diff >= m_frameTime) {
			m_module->OnFrame(diff);
			m_diff = 0;
		} else m_diff += diff;


		m_module->OnLoop(diff);

		sf::Sleep(0.0001f);

		diff = time.GetElapsedTime()*1000.0f;

		time.Reset();
	}
	m_module->OnClose();
	return true;
}

bool Engine::Run( Module* module )
{
	if(!module) return false;
	if(!module->IsAlive()) return false;

	std::stack<Module*> stack;
	stack.push(module);
	Module* current = stack.top(); stack.pop();
	while(current || stack.size() > 0) {
		if(current) {
			current->OnLoad();			//load it
		} else {
			current = stack.top();	
			stack.pop();
			if(current == NULL) continue;
		}

		Execute(current);				//execute it
		Module* old = current;
		//current = current->m_nextModule;
		if(!old->IsAlive()) {			//unload it if dead!
			old->OnUnload();
			//delete old;				//this doesn't feel right! you don't own it!!!
		} else {
			stack.push(current);
			old = NULL;
		}
	}

	return true;
}

bool Engine::Manage( ModuleScheduler* scheduler )
{
	if(!scheduler) return false;
	while(Module* module = scheduler->GetNextModule()) {
		module->SetWindow(&window);
		scheduler->StartModule();
			Execute(module);
		scheduler->StopModule();
	}
	return true;
}